package com.logic.landseaserver.models.payment.impl;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;

import com.logic.landseaserver.common.LandeaConstants;
import com.logic.landseaserver.domain.*;
import com.logic.landseaserver.persistence.read.ContractReadMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.logic.common.security.SecurityUtils;
import com.logic.landseaserver.common.LandeaConstants.AccountStatus;
import com.logic.landseaserver.common.LandeaConstants.QueryUesdCodeType;
import com.logic.landseaserver.common.enums.BillStatusEnum;
import com.logic.landseaserver.common.exception.LandseaException;
import com.logic.landseaserver.common.exception.ResultCodes.PaymentResultCode;
import com.logic.landseaserver.common.util.ConstantChar;
import com.logic.landseaserver.models.authcode.service.AuthCodeService;
import com.logic.landseaserver.models.independent.service.BillIndependentService;
import com.logic.landseaserver.models.payment.PaymentConstant;
import com.logic.landseaserver.models.payment.PaymentConstant.BillTypeCode;
import com.logic.landseaserver.models.payment.bean.PaymentHelperBean;
import com.logic.landseaserver.models.payment.service.AbstractPaymentResponseHandler;
import com.logic.landseaserver.models.payment.service.PaymentService;
import com.logic.landseaserver.models.prepayment.bean.AotuPayBill;
import com.logic.landseaserver.models.prepayment.service.PrepaymentService;
import com.logic.landseaserver.persistence.read.BillDetailReadMapper;
import com.logic.landseaserver.persistence.read.PreOffrentBillReadMapper;
import com.logic.landseaserver.persistence.write.MonthlyBillWriteMapper;
import com.logic.landseaserver.service.IDdLockService;
import com.logic.landseaserver.ws.dto.BillDTO;

/**
 * 
 *
 * 项目名称：system-server</br>
 * 类名称：MonthBillResponseHandler</br>
 * 类描述：月结账单结果通知处理</br>
 * 创建人：Aaron</br>
 * 创建时间：2017年7月19日 下午4:33:21</br>
 * 
 * @version 1.0
 *
 */
@Service(BillTypeCode.MONTH_PAY + PaymentConstant.PAYMENT_RESPONSE_SUFFIX)
public class MonthBillResponseHandler extends AbstractPaymentResponseHandler
{
    @Autowired
    private PaymentService paymentService;
    
    @Autowired
    private MonthlyBillWriteMapper monthlyBillWriteMapper;
    
    @Autowired
    private BillDetailReadMapper billDetailReadMapper;
    
    @Autowired
    private IDdLockService ddLockService;
    
    @Autowired
    private BillIndependentService billIndependentService;
    
    @Autowired
    private AuthCodeService authCodeService;
    
    @Autowired
    private PreOffrentBillReadMapper preOffrentBillReadMapper;

    @Autowired
    private ContractReadMapper contractReadMapper;
    
    @Autowired
    private PrepaymentService prepaymentService;
    
    @Override
    protected void doLocalBusiness(BillPayment payment, PaymentHelperBean helperObject, Map<String, Object> resultMap)
        throws LandseaException
    {
        // 更新bill表状态及金额
        BillDTO bill = paymentService.updateBillStateAndMoney(payment.getBillId(), payment.getMoney());
       
        String logInfo = getLog(payment, payment.getId());
        LOGGER.info(logInfo + "updateBillStateAndMoney finished.");
        
        // 如果已全部支付完成
        if (BillStatusEnum.BIST2.getCode().equals(bill.getBillStatus()))
        {
            updateMonthlyBill(bill, logInfo);
            LOGGER.info(logInfo + "updateMonthlyBill finished.");
            
            // ADD by Junny 退房账单特殊处理 将往期所有其他费项都改为已支付
            if (ConstantChar.BILLING_OF_OFFRENT_BILL.equals(bill.getName()))
            {
                MonthlyBill monthlyBill = new MonthlyBill();
                monthlyBill.setBillNo(bill.getBillNo());
                monthlyBill.setContractId(bill.getContractId());
                monthlyBill.setStatus(BillStatusEnum.BIST2.getCode());
                monthlyBill.setLastModifiedBy(SecurityUtils.getCurrentLogin().getUserId());
                monthlyBillWriteMapper.updateMonthlyBillByOffBill(monthlyBill);
                // 微众和pos处理月结往BalanceSheet里面修改数据
                billIndependentService.monUpdateBalanceSheetRent(bill.getContractId(), payment.getTime());
                
                // 退租结束，更新账户为正常
                prepaymentService.updateAccountStatusByContract(bill.getContractId(), AccountStatus.NORMAL);
                LOGGER.info("退租账单支付完毕,已更新账户contractId=" + bill.getContractId() + "的账户状态为：正常.");
            }

            //Add by Junny 如果是第二期，且是续租合同，则需处理A合同的其他费项
            String secondBillName = bill.getBillNo().substring(0,10)+"02";
            if(secondBillName.equals(bill.getBillNo())){
                Contract contract = contractReadMapper.selectByPrimaryKey(bill.getContractId());
                if(contract.getOriginalCId()!=null && contract.getRentType()!=null) {
                    if(contract.getRentType().equals(LandeaConstants.ReRentType.RERENT)){
                        MonthlyBill monthlyBill = new MonthlyBill();
                        monthlyBill.setBillNo(bill.getBillNo());
                        monthlyBill.setContractId(contract.getOriginalCId());
                        monthlyBill.setStatus(BillStatusEnum.BIST2.getCode());
                        monthlyBill.setLastModifiedBy(SecurityUtils.getCurrentLogin().getUserId());
                        monthlyBillWriteMapper.updateMonthlyBillByOffBill(monthlyBill);
                    }
                }
            }
            
            //银石支付往balanceSheet里面修改数据
            billIndependentService.monUpdateBalanceSheet(bill.getId(), payment.getTime());
            
            // 查询是否有房租
            BillDetail billDetail = billDetailReadMapper.checkIsContainRent(payment.getBillId());
            if (null != billDetail)
            {
                // 如果有房租，则要重置密码有效期为房租截止日期,不需要发送短信
                ddLockService.resetPasswordEffectiveTime(null, bill.getContractId(), null);
            }
        }
        
        // 更新授权码为已使用状态
        // 先查询是否是退房账单
        PreOffrentBill preOffrentBill = preOffrentBillReadMapper.queryByContractId(bill.getContractId());
        if (null != preOffrentBill)
        {
            // 退房账单时，mainId为退房结算单的ID
            authCodeService.updateCouponStatusAfterPay(QueryUesdCodeType.OFFRENT, preOffrentBill.getId());
        }
        else
        {
            // 月结账单时，mainId为BillId
            authCodeService.updateCouponStatusAfterPay(QueryUesdCodeType.MONTHBILL, payment.getBillId());
        }
    }
    
    private void updateMonthlyBill(BillDTO bill, String logInfo) throws LandseaException
    {
        try
        {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM");
            Date month = sdf.parse(bill.getBillMonth());
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(month);
            calendar.add(Calendar.MONTH, -1);
            String lastBillMonth = sdf.format(calendar.getTime());
            
            MonthlyBill monthlyBill = new MonthlyBill();
            monthlyBill.setBillMonth(lastBillMonth);
            monthlyBill.setBillNo(bill.getBillNo());
            monthlyBill.setContractId(bill.getContractId());
            monthlyBillWriteMapper.updateMonthlyBillStatusAndBillNo(monthlyBill);

        }
        catch (Exception e)
        {
            LOGGER.error(logInfo + "updateMonthlyBill failed.", e);
            throw LandseaException.createException(PaymentResultCode.E00150017, e);
        }
    }
    
    @Override
    protected String getProcessClassName()
    {
        return this.getClass().getSimpleName();
    }

    /**    
     * [描述]：</br>
     *
     * @param aotuPayBill
     * @param payment
     * @throws LandseaException
     *
    */
    @Override
    public void aotoPayDoLocalBusiness(AotuPayBill aotuPayBill, BillPayment payment)
        throws LandseaException
    {
        // 更新bill表状态及金额
        BillDTO bill = paymentService.updateBillStateAndMoney4AutoPay(aotuPayBill, payment);
        
        String logInfo = "余额自动抵扣月结账单处理|";
        LOGGER.info(logInfo + "更新月结账单状态及金额完毕.");
        
        // 如果已全部支付完成
        if (BillStatusEnum.BIST2.getCode().equals(bill.getBillStatus()))
        {
            updateMonthlyBill(bill, logInfo);
            LOGGER.info(logInfo + "更新月结表完毕.");
            
            // ADD by Junny 退房账单特殊处理 将往期所有其他费项都改为已支付
            if (ConstantChar.BILLING_OF_OFFRENT_BILL.equals(bill.getName()))
            {
                MonthlyBill monthlyBill = new MonthlyBill();
                monthlyBill.setBillNo(bill.getBillNo());
                monthlyBill.setContractId(bill.getContractId());
                monthlyBill.setStatus(BillStatusEnum.BIST2.getCode());
                monthlyBill.setLastModifiedBy(SecurityUtils.getCurrentLogin().getUserId());
                monthlyBillWriteMapper.updateMonthlyBillByOffBill(monthlyBill);
                // 微众和pos处理月结往BalanceSheet里面修改数据
                billIndependentService.monUpdateBalanceSheetRent(bill.getContractId(), payment.getTime());
            }
            
            //银石支付往balanceSheet里面修改数据
            billIndependentService.monUpdateBalanceSheet(bill.getId(), payment.getTime());
            
            // 查询是否有房租
            BillDetail billDetail = billDetailReadMapper.checkIsContainRent(payment.getBillId());
            if (null != billDetail)
            {
                // 如果有房租，则要重置密码有效期为房租截止日期,不需要发送短信
                ddLockService.resetPasswordEffectiveTime(null, bill.getContractId(), null);
            }
        }
        
        // 更新授权码为已使用状态
        // 先查询是否是退房账单
        PreOffrentBill preOffrentBill = preOffrentBillReadMapper.queryByContractId(bill.getContractId());
        if (null != preOffrentBill)
        {
            // 退房账单时，mainId为退房结算单的ID
            authCodeService.updateCouponStatusAfterPay(QueryUesdCodeType.OFFRENT, preOffrentBill.getId());
        }
        else
        {
            // 月结账单时，mainId为BillId
            authCodeService.updateCouponStatusAfterPay(QueryUesdCodeType.MONTHBILL, payment.getBillId());
        }
    }
}
